/**
 * @file Define the Partner service class
 * 
 * @author Steve Gao<gaofu@parlly.com>
 */

const request       = require('request');
const async         = require('async');
const utils         = require('../utils');
const BaseService   = require('./base-service').BaseService;

const {SystemServices, Configuration} = require('../constants');

/**
 * Wrap all methods about partners
 * 
 * @class PartnerService
 * @extends {BaseService}
 */
class PartnerService extends BaseService {

    /**
     * Get partners by condition
     * 
     * @param {Object} params 
     * @param {Function} parentCallback 
     * 
     * @memberof PartnerService
     */
    getPartners(params, parentCallback) {
        var count = Number(params && params.count || 5);
        var pageIndex = params && params.pageIndex || 1;
        pageIndex = Number(pageIndex < 1 ? 1 : pageIndex);
        var me = this;
        this.acquireStorageClients({
            mysql: true
        }, (clients) => {
            var mysql = clients.mysql;
            var start = (pageIndex - 1) * count;
            var limit = count;
            async.waterfall([
                (callback) => {
                    mysql.query("SELECT * FROM wall_partners ORDER BY id LIMIT ?, ?", [start, count], (error, result) => {
                        var partners = [];
                        if (error) {
                            me.logger.error(error);
                        } else {
                            result.forEach((partner) => {
                                partners.push({
                                    id: partner.id,
                                    name: partner.name,
                                    logo: partner.logo
                                })
                            });
                        }
                        callback(null, partners);
                    });
                }, (partners) => {
                    me.releaseStorageClients(clients);
                    parentCallback({
                        success: true,
                        data: partners
                    });
                }
            ])
        }, (errors) => {
            me.logger.error(errors);
            parentCallback({
                success: false,
                error: '系统内部错误，请稍后再试！'
            });
        });
    }

    /**
     * Get partner's TV App Versions
     * 
     * @param {Object} params 
     * @param {Function} parentCallback 
     * 
     * @memberof PartnerService
     */
    getPartnerTVAppVersions(params, parentCallback) {
        var partnerId = params.partnerId;
        if (!partnerId) {
            return parentCallback({
                success: false,
                error: "请制定一个合作厂商！"
            });
        }
        var count = Number(params && params.count || 5);
        var pageIndex = params && params.pageIndex || 1;
        pageIndex = Number(pageIndex < 1 ? 1 : pageIndex);

        var me = this;
        this.acquireStorageClients({
            mysql: true
        }, (clients) => {
            var mysql = clients.mysql;
            var start = (pageIndex - 1) * count;
            var limit = count;
            async.waterfall([
                (callback) => {
                    mysql.query("SELECT * FROM wall_tv_app_releases WHERE partner_id = ? ORDER BY last_updated_date DESC LIMIT ?, ?", [partnerId, start, limit], (error, result) => {
                        var versions = [];
                        if (error) {
                            me.logger.error(error);
                        } else {
                            result.forEach((version) => {
                                versions.push({
                                    id: version.id,
                                    version: version.version,
                                    version_code: version.version_code,
                                    release_notes: version.release_notes,
                                    download_url: version.download_url,
                                    is_active: version.is_active
                                });
                            });
                        }
                        callback(null, versions);
                    });
                }, (versions) => {
                    me.releaseStorageClients(clients);
                    parentCallback({
                        success: true,
                        data: versions
                    });
                }
            ])
        }, (errors) => {
            me.logger.error(errors);
            parentCallback({
                success: false,
                error: "系统内部错误，请稍后再试！"
            })
        })
    }

    /**
     * Create new TV App version
     * 
     * @param {Object} data 
     * @param {Function} parentCallback 
     * @returns 
     * 
     * @memberof PartnerService
     */
    createNewTVAppVersion(data, parentCallback) {
        if (!data.partner_id 
            || !data.version 
            || !data.version_code 
            || !data.release_notes 
            || !data.download_url) {
            return parentCallback({
                success: false,
                error: "参数错误，请检查：partner_id, version, version_code, release_notes以及download_url"
            });
        }

        var me = this;
        this.acquireStorageClients({
            mysql: true
        }, (clients) => {
            var mysql = clients.mysql;

            async.waterfall([
                (callback) => {
                    mysql.query("SELECT * FROM wall_tv_app_releases WHERE partner_id = ? AND (version = ? OR version_code = ?)", [Number(data.partner_id), data.version, Number(data.version_code)], (error, result) => {
                        if (error) {
                            me.logger.error(error);
                            callback(null, true, true);
                        } else {
                            callback(null, result.length > 0, false);
                        }
                    });
                }, (existed, hasError, callback) => {
                    if (hasError || existed) {
                        me.releaseStorageClients(clients);
                    }

                    if (hasError) {
                        return parentCallback({
                            success: false,
                            error: "系统内部错误，请稍后再试！"
                        });
                    }

                    if (existed) {
                        return parentCallback({
                            success: false,
                            error: "版本或版本号已经存在！"
                        });
                    }

                    mysql.query("INSERT INTO wall_tv_app_releases(partner_id, version, version_code, release_notes, download_url, created_by, is_active) VALUES(?, ?, ?, ?, ?, ?, ?)",
                        [Number(data.partner_id), data.version, Number(data.version_code), data.release_notes, data.download_url, 1001, 1], (error, result) => {
                        if (error) {
                            me.logger.error(error);
                            callback(null, true, -1);
                        } else {
                            callback(null, false, result.insertId);
                        }
                    });
                }, (hasError, lastId) => {
                    me.releaseStorageClients(clients);
                    if (hasError) {
                        parentCallback({
                            success: false,
                            error: "系统内部错误，请稍后再试！"
                        })
                    } else {
                        parentCallback({
                            success: true,
                            data: lastId
                        })
                    }
                }
            ])
        }, (errros) => {
            me.logger.error(errors);
            parentCallback({
                success: false,
                error: "系统内部错误，请稍后再试！"
            })
        });
    }

    /**
     * Update an existed TV App version
     * 
     * @param {Object} data 
     * @param {Function} parentCallback 
     * 
     * @memberof PartnerService
     */
    updateTVAppVersion(data, parentCallback) {

        var me = this;
        this.acquireStorageClients({
            mysql: true
        }, (clients) => {
            var mysql = clients.mysql;

            async.waterfall([
                (callback) => {
                    mysql.query("SELECT * FROM wall_tv_app_releases WHERE id = ?", [Number(data.version_id)], (error, result) => {
                        if (error) {
                            me.logger.error(error);
                            callback(null, true, null);
                        } else {
                            callback(null, false, result.length > 0 ? result[0] : null);
                        }
                    });
                }, (hasError, version, callback) => {
                    if (hasError || !version) {
                        me.releaseStorageClients(clients);
                    }

                    if (hasError) {
                        return parentCallback({
                            success: false,
                            error: "系统内部错误，请稍后再试！"
                        });
                    }

                    if (!version) {
                        return parentCallback({
                            success: false,
                            error: "该版本不存在，不能更新！"
                        });
                    }

                    if (version.partner_id !== Number(data.partner_id)) {
                        return parentCallback({
                            success: false,
                            error: "该版本不属于当前合作伙伴！"
                        });
                    }

                    var statements = [];
                    var values = [];
                    if (data.version) {
                        statements.push("version = ?");
                        values.push(data.version);
                    }

                    if (data.version_code) {
                        statements.push("version_code = ?");
                        values.push(Number(data.version_code));
                    }

                    if (data.release_notes) {
                        statements.push("release_notes = ?");
                        values.push(data.release_notes);
                    }

                    if (data.download_url) {
                        statements.push("download_url = ?");
                        values.push(data.download_url);
                    }

                    if (statements.length === 0) {
                        me.releaseStorageClients(clients);
                        return parentCallback({
                            success: false,
                            error: "没有需要更新的数据！"
                        });
                    }
                    
                    values.push(data.version_id);
                    mysql.query(`UPDATE wall_tv_app_releases SET ${statements.join(", ")} WHERE id = ?`, values, (error, result) => {
                        if (error) {
                            me.logger.error(error);
                            callback(null, true);
                        } else {
                            callback(null, false);
                        }
                    });
                }, (hasError) => {
                    me.releaseStorageClients(clients);
                    if (hasError) {
                        parentCallback({
                            success: false,
                            error: "系统内部错误，请稍后再试！"
                        });
                    } else {
                        parentCallback({
                            success: true,
                            data: "OK"
                        });
                    }
                }
            ])
        }, (errors) => {
            me.logger.error(errors);
            parentCallback({
                success: false,
                error: "系统内部错误，请稍后再试！"
            });
        })
    }
}

exports.PartnerService = PartnerService;